package portal.manager.templator;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;

/**
* A cache manager for MiniTemplator objects.
* This class is used to cache MiniTemplator objects in memory, so that
* each template file is only read and parsed once.
*
* <p>
* Home page: <a href="http://www.source-code.biz/MiniTemplator" target="_top">www.source-code.biz/MiniTemplator</a><br>
* License: This module is released under the <a href="http://www.gnu.org/licenses/lgpl.html" target="_top">GNU/LGPL</a> license.<br>
* Copyright 2003-2006: Christian d'Heureuse, Inventec Informatik AG, Switzerland. All rights reserved.<br>
* This product is provided "as is" without warranty of any kind.<br>
*
* <p>
* Version history:<br>
* 2004-11-06 chdh: Module created.<br>
* 2004-11-07 chdh: Method "clear" added.<br>
* 2006-07-07 chdh: Extended constructor with <code>charset</code> argument added.
*/
public class MiniTemplatorCache {

private Charset              charset;                      // charset used for file i/o
private String               subtemplateBasePath;          // base path for relative file names of subtemplates, may be null
private HashMap<String,MiniTemplator> cache;               // buffered MiniTemplator objects

/**
* Creates a new MiniTemplatorCache object.
*/
public MiniTemplatorCache() {
   this (null,Charset.defaultCharset()); }

/**
* Creates a new MiniTemplatorCache object.
* @param  subtemplateBasePath  a file system directory path, to be used for subtemplates.
*                              Or null to use the parent directories of the template files.
* @param  charset              the character set to be used for reading template files and writing output files.
*/
public MiniTemplatorCache (String subtemplateBasePath, Charset charset) {
   this.subtemplateBasePath = subtemplateBasePath;
   this.charset = charset;
   cache = new HashMap<String,MiniTemplator>(); }

/**
* Returns a cloned MiniTemplator object from the cache.
* If there is not yet a MiniTemplator object with the specified <code>templateFileName</code>
* in the cache, a new MiniTemplator object is created and stored in the cache.
* Then the cached MiniTemplator object is cloned and the clone object is returned.
* @param  templateFileName  the name of the template file.
* @return                   a cloned and reset MiniTemplator object.
*/
public MiniTemplator get (String templateFileName)
      throws IOException, MiniTemplator.TemplateSyntaxException {
   return getClone (templateFileName,null); }

/**
* Returns a cloned MiniTemplator object from the cache.
* Same as {@link #get(String)}, but with a <code>subtemplateBasePath</code> parameter.
* @param  templateFileName     the name of the template file.
* @param  subtemplateBasePath  a file system directory path, to be used for subtemplates.
* @return                      a cloned and reset MiniTemplator object.
*/
public MiniTemplator get (String templateFileName, String subtemplateBasePath)
      throws IOException, MiniTemplator.TemplateSyntaxException {
   return getClone (templateFileName,subtemplateBasePath); }

private synchronized MiniTemplator getClone (String templateFileName, String subtemplateBasePath)
      throws IOException, MiniTemplator.TemplateSyntaxException {
   MiniTemplator mt = cache.get(templateFileName);
   if (mt == null) {
      File file = new File(templateFileName);
      String subtemplateBasePath2 = subtemplateBasePath;
      if (subtemplateBasePath2 == null) subtemplateBasePath2 = this.subtemplateBasePath;
      if (subtemplateBasePath2 == null) subtemplateBasePath2 = file.getParent();
      mt = new MiniTemplator(file,subtemplateBasePath2,charset);
      cache.put (templateFileName,mt); }
   return mt.cloneReset(); }

/**
* Clears the cache.
*/
public synchronized void clear() {
   cache.clear(); }

} // end class MiniTemplatorCache
